package com.mini;


import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.SQLException;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

import com.j256.ormlite.android.apptools.OpenHelperManager;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.DeleteBuilder;
import com.j256.ormlite.stmt.UpdateBuilder;
import com.mini.dao.DaoModelo;
import com.mini.dao.DaoPersistencia;
import com.mini.dao.DaoTimestamp;
import com.mini.db.DataBaseHelper;
import com.mini.familia.Familia1;
import com.mini.parser.Parser;
import com.mini.values.Edicion;
import com.mini.values.Modelo;
import com.mini.values.Persistencia;
import com.mini.values.Timestamp;


public class MiniActivity extends Activity
{
	private DataBaseHelper databaseHelper = null;







	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		try
		{

			ConnectivityManager conMgr =  (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo red  = conMgr.getActiveNetworkInfo();
			boolean conexionInternet = red!=null && red.getState() == NetworkInfo.State.CONNECTED;

			Dao<Persistencia, Integer> dao = getHelper().darDaoPersistencia();
			if(!DaoPersistencia.hayPersistencia(dao) && conexionInternet)
			{
				DaoPersistencia.primeraVez(dao);
				new FetchInfoInicialFamilia().execute("hola");
			}
			else
			{
				new ActualizacionInfoFamilia().execute("");
			}
		}
		catch(Exception e)
		{
			//Manejar las excepciones de la base de datos

			Log.d("mensaje", e.getMessage());
		}

	}



	@Override
	protected void onDestroy() 
	{
		super.onDestroy();

		//Manejo del objeto DataBaseHelper
		if(databaseHelper != null)
			OpenHelperManager.releaseHelper();
		databaseHelper = null;
	}


	/**
	 * Metodo necesario para la creacion de un objeto DAO para acceder a cada uno de las tablas
	 * @return
	 */
	public DataBaseHelper getHelper()
	{
		if(databaseHelper == null)
			databaseHelper = OpenHelperManager.getHelper(this,DataBaseHelper.class);
		return databaseHelper;
	}

	///////////////////////////////////////////////////////////////////////////
	//Metodos para hacer el fetch inicial y actualizacion de la seccion familia
	////////////////////////////////////////////////////////////////////////////

	private class ActualizacionInfoFamilia extends AsyncTask<String, Integer, Boolean>
	{

		private JSONArray modelos=null;

		private JSONArray ediciones=null;
		
		private JSONObject actualizacion = null;
		
		private JSONObject tipo = null;

		private Dao<Modelo, String> daoModelo;

		private Dao<Edicion, String>  daoEdicion;
		
		private boolean hayActualizaciones;
		
		private String timestamp;

		@Override
		protected Boolean doInBackground(String... params) 
		{
			daoEdicion = darDaoEdicion();
			daoModelo = darDaoModelo();
			
			Parser jparser = new Parser();
			JSONObject jsonObject = jparser.getJSONFromUrl(getString(R.string.CONSTANTE_ACTUALIZAR_MODELO_EDICION_URL));
			
			 try 
			 {
				hayActualizaciones = jsonObject.getBoolean(getString(R.string.TAG_HAY_ACTUALIZACIONES));
				if(hayActualizaciones)
				{
					timestamp = jsonObject.getString(getString(R.string.TAG_TIMESTAMP));
					
					JSONArray actualizaciones = jsonObject.getJSONArray(getString(R.string.TAG_ACTUALIZACIONES));
					
					JSONObject modelo;
					
					JSONObject edicion;
					
					for(int i = 0; i < actualizaciones.length(); i ++)
					{
						actualizacion = actualizaciones.getJSONObject(i);
						
						
						//Operaciones para actualizar los modelos y las ediciones
						if(actualizacion.get(getString(R.string.TAG_ACCION)).equals(getString(R.string.TAG_ACTUALIZACIONES)))
						{
							if(actualizacion.get(getString(R.string.TAG_TIPO)).equals("modelo"))
							{
								
								modelo = actualizacion.getJSONObject("modelo");
								
								UpdateBuilder<Modelo, String> updateBuilder = daoModelo.updateBuilder();
								updateBuilder.updateColumnValue("nombre", modelo.getString(getString(R.string.TAG_NOMBRE_MODELO)));
								updateBuilder.updateColumnValue("descripcion", modelo.getString(getString(R.string.TAG_DESCRIPCION_MODELO)));
								
								//Manejo de la imagen
								String nombreImagenAEliminar = getString(R.string.CONSTANTE_NOMBRE_IMAGEN_MODELO) + actualizacion.getString(getString(R.string.TAG_NOMBRE_MODELO));
								eliminarImagen(nombreImagenAEliminar);
								String url = modelo.getString(getString(R.string.TAG_IMAGEN_MODELO));
								String nombreImagen = getString(R.string.CONSTANTE_NOMBRE_IMAGEN_MODELO)+ modelo.getString(getString(R.string.TAG_NOMBRE_MODELO));
								descargarImagen(url, nombreImagen);
								
								//Continuacion del update
								updateBuilder.updateColumnValue("imagen", nombreImagen);
								updateBuilder.where().eq("nombre", actualizacion.getString(getString(R.string.TAG_NOMBRE_MODELO)));
								daoModelo.update(updateBuilder.prepare());
							}
							else
							{
								edicion = actualizacion.getJSONObject("edicion");
								
								UpdateBuilder<Edicion, String> updateBuilder = daoEdicion.updateBuilder();
								
								//Manejo de la imagen
								String nombreImagenAeliminar = getString(R.string.CONSTANTE_NOMBRE_IMAGEN_EDICION) + actualizacion.getString(getString(R.string.TAG_IMAGEN_EDICION));
								eliminarImagen(nombreImagenAeliminar);
								String urlImagen = edicion.getString(getString(R.string.TAG_IMAGEN_EDICION));
								String nombreImagen = getString(R.string.CONSTANTE_NOMBRE_IMAGEN_EDICION) + edicion.getString(getString(R.string.TAG_NOMBRE_EDICION));
								descargarImagen(urlImagen, nombreImagen);
								
								updateBuilder.updateColumnValue("imagen", nombreImagen);
								updateBuilder.updateColumnValue("test_drive",Boolean.parseBoolean(edicion.getString(getString(R.string.TAG_TEST_DRIVE_EDICION))));
								updateBuilder.updateColumnValue("descripcion", edicion.getString(getString(R.string.TAG_DESCRIPCION_EDICION)));
								updateBuilder.updateColumnValue("nombre", edicion.getString(getString(R.string.TAG_NOMBRE_EDICION)));
								
								//Manejo de la imagen del thumbnial
								String nombreThumbEliminar = getString(R.string.CONSTANTE_NOMBRE_THUMBNAIL_EDICION) + actualizacion.getString(getString(R.string.TAG_IMAGEN_THUMBNAIL_EDICION));
								eliminarImagen(nombreThumbEliminar);
								String urlThumbnail = edicion.getString(getString(R.string.TAG_IMAGEN_THUMBNAIL_EDICION));
								String nombreThumbnail = getString(R.string.CONSTANTE_NOMBRE_THUMBNAIL_EDICION) + edicion.getString(getString(R.string.TAG_NOMBRE_EDICION));
								descargarImagen(urlThumbnail, nombreThumbnail);
								
								updateBuilder.updateColumnValue("thumbnail", nombreThumbnail);
								updateBuilder.where().eq("modelo", actualizacion.getString(getString(R.string.TAG_NOMBRE_MODELO_EDICION)));
								daoEdicion.update(updateBuilder.prepare());
								
								
							}
						}
						
						//Operaciones para borrar modelos y ediciones
						else if(actualizacion.get(getString(R.string.TAG_ACCION)).equals(getString(R.string.TAG_ELIMINAR)))
						{
							if(actualizacion.get(getString(R.string.TAG_TIPO)).equals("modelo"))
							{
								DeleteBuilder<Modelo, String> deleteBuilder = daoModelo.deleteBuilder();
								deleteBuilder.where().eq("nombre", actualizacion.get(getString(R.string.TAG_NOMBRE_MODELO)));
								
								daoModelo.delete(deleteBuilder.prepare());
							}
							else
							{
								DeleteBuilder<Edicion, String> deleteBuilder = daoEdicion.deleteBuilder();
								deleteBuilder.where().eq("nombre",actualizacion.get(getString(R.string.TAG_NOMBRE_EDICION)));
								daoEdicion.delete(deleteBuilder.prepare());
							}
								
						}
						else if(actualizacion.get(getString(R.string.TAG_ACCION)).equals(getString(R.string.TAG_CREAR)))
						{
							if(actualizacion.get(getString(R.string.TAG_TIPO)).equals("modelo"))
							{
								modelo = actualizacion.getJSONObject("modelo");
								String descripcion = modelo.getString(getString(R.string.TAG_DESCRIPCION_MODELO));
								String nombre = modelo.getString(getString(R.string.TAG_NOMBRE_MODELO));
								String urlImagen = modelo.getString(getString(R.string.TAG_IMAGEN_MODELO));
								
								
								String nombreImagen = getString(R.string.CONSTANTE_NOMBRE_IMAGEN_MODELO) + nombre;
								descargarImagen(urlImagen, nombreImagen);
								Modelo m = new Modelo(nombreImagen,nombre,descripcion);
								daoModelo.create(m);
							}
							else
							{
								edicion = actualizacion.getJSONObject("edicion");
								
								
								String nombre = edicion.getString(getString(R.string.TAG_NOMBRE_EDICION));
								
								//Manejo imagen
								String urlImagen = edicion.getString(getString(R.string.TAG_IMAGEN_EDICION));
								String nombreImagen = getString(R.string.CONSTANTE_NOMBRE_IMAGEN_EDICION) + nombre;
								descargarImagen(urlImagen, nombreImagen);
								boolean test_drive = Boolean.parseBoolean(edicion.getString(getString(R.string.TAG_TEST_DRIVE_EDICION)));
								String descripcion = edicion.getString(getString(R.string.TAG_DESCRIPCION_EDICION));
								
								//Manejo thumbnail
								String urlImagenThumbnail = edicion.getString(getString(R.string.TAG_IMAGEN_THUMBNAIL_EDICION));
								String nombreThumbnail = getString(R.string.CONSTANTE_NOMBRE_IMAGEN_EDICION);
								descargarImagen(urlImagenThumbnail, nombreThumbnail);
								
								
								String nombreModelo = edicion.getString(getString(R.string.TAG_NOMBRE_MODELO_EDICION));
								Modelo m = DaoModelo.darModelo(daoModelo, nombreModelo);
								
								Edicion e = new Edicion(nombreImagen,nombre,descripcion,nombreThumbnail,test_drive,m);
								daoEdicion.create(e);
								
								
							}
						}

						
		
					}
					
					
					
					
				}
			} 
			 catch (JSONException e) 
			 {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
			 catch (SQLException e) 
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			return null;
		}

	}


	private class FetchInfoInicialFamilia extends AsyncTask<String, Integer, Boolean>
	{

		private JSONArray modelos=null;

		private JSONArray ediciones=null;

		private Dao<Modelo, String> daoModelo;

		private Dao<Edicion, String>  daoEdicion;
		
		private Dao<Timestamp, Integer> daoTimestamp;

		ProgressDialog progress;

		@Override
		protected void onPreExecute() 
		{
			super.onPreExecute();
			progress = ProgressDialog.show(darContexto(),"","Cargando...",false);
		}



		@Override
		protected Boolean doInBackground(String... params) 
		{

			daoEdicion = darDaoEdicion();
			daoModelo = darDaoModelo();
			daoTimestamp = darDaoTimestamp();

			Parser jparser = new Parser();
			JSONObject jsonObject = jparser.getJSONFromUrl("http://minicolombia.herokuapp.com/familiaMini/dar-modelos/");

			
			
			
			Modelo modelo;

			try 
			{
				String timeStamp = jsonObject.getString(getString(R.string.TAG_TIMESTAMP));
				
				DaoTimestamp.primeraVez(daoTimestamp, timeStamp);
				
				modelos = jsonObject.getJSONArray(getString(R.string.TAG_MODELO));

				for(int i = 0 ; i < modelos.length(); i++)
				{
					JSONObject object_modelo = modelos.getJSONObject(i);

					String imagen_modelo = object_modelo.getString(getString(R.string.TAG_IMAGEN_MODELO));
					String nombre_modelo = object_modelo.getString(getString(R.string.TAG_NOMBRE_MODELO));
					String descripcion_modelo = object_modelo.getString(getString(R.string.TAG_DESCRIPCION_MODELO));

					String nombre_imagen =getString(R.string.CONSTANTE_NOMBRE_IMAGEN_MODELO) + nombre_modelo;

					descargarImagen(imagen_modelo, nombre_imagen);

					modelo = new Modelo(nombre_imagen, nombre_modelo, descripcion_modelo);



					daoModelo.create(modelo);

					Edicion edicion;

					ediciones = object_modelo.getJSONArray(getString(R.string.TAG_EDICIONES));

					for(int j = 0; j< ediciones.length(); j ++)
					{
						JSONObject object_edicion= ediciones.getJSONObject(j);

						String nombre_edicion = object_edicion.getString(getString(R.string.TAG_NOMBRE_EDICION));
						
						//Manejo Imagen
						String imagen_edicion =  object_edicion.getString(getString(R.string.TAG_IMAGEN_EDICION));
						String nombreImagen = getString(R.string.CONSTANTE_NOMBRE_IMAGEN_EDICION) + nombre_edicion;
						descargarImagen(imagen_edicion, nombre_imagen);
						
						String descripcion_edicion = object_edicion.getString(getString(R.string.TAG_DESCRIPCION_EDICION));
						
						//Manejo imagen thumbnail
						String imagen_thumbnail_edicion = object_edicion.getString(getString(R.string.TAG_IMAGEN_THUMBNAIL_EDICION));
						String nombre_thumbnail = getString(R.string.CONSTANTE_NOMBRE_THUMBNAIL_EDICION) + nombre_edicion;
						descargarImagen(imagen_thumbnail_edicion, nombre_thumbnail);
						boolean test_drive_edicion = Boolean.parseBoolean(object_edicion.getString(getString(R.string.TAG_TEST_DRIVE_EDICION)));

						edicion = new Edicion(nombreImagen, nombre_edicion, descripcion_edicion, nombre_thumbnail, test_drive_edicion,modelo);
						daoEdicion.create(edicion);
					}


				}
			} 
			catch (JSONException e) 
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
						catch (SQLException e) 
						{
							// TODO Auto-generated catch block
							e.printStackTrace();
						}


			List<Modelo> modelos;
			List<Edicion> ediciones;
			List<Persistencia> persistencia;
			try {
				
				persistencia= darDaoPersistencia().queryForAll();
				
				modelos = daoModelo.queryForAll();
				for (Modelo m : modelos)
				{
					Log.d("modelos", m.toString());
				}
				
				ediciones = daoEdicion.queryForAll();
				for(Edicion e : ediciones)
				{
					String s = e.toString();
					Log.d("edicion", s);
				}
				
			} 
			catch (SQLException e1) 
			{
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}


			
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) 
		{
			if(progress.isShowing())
				progress.dismiss();
			pasarAFamily();

		}
	}



	






	//////////////////////////////////////////////////////////////////
	//Metodos para obtener los objetos DAO de cada una de las tablas
	//////////////////////////////////////////////////////////////////

	public Dao<Edicion, String> darDaoEdicion()
	{

		Dao<Edicion, String> daoEdicion = null;
		try 
		{
			daoEdicion = getHelper().darDaoEdicion();
		} 
		catch (SQLException e) 
		{
			e.printStackTrace();
		}
		return daoEdicion;
	}

	public Dao<Modelo,String> darDaoModelo()
	{
		Dao<Modelo, String> daoModelo = null;
		
		try 
		{
			daoModelo = getHelper().darDaoModelo();
		} 
		catch (SQLException e) 
		{
			e.printStackTrace();
		}
		return daoModelo;

	}
	
	public Dao<Timestamp, Integer> darDaoTimestamp()
	{
		Dao<Timestamp, Integer> daoTimestamp = null;
		
		try 
		{
			daoTimestamp = getHelper().darDaoTimestamp();
		} 
		catch (SQLException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return daoTimestamp;
	}
	
	public Dao<Persistencia, Integer> darDaoPersistencia()
	{
		Dao<Persistencia, Integer> daoPErsistencia = null;
		
		try
		{
			daoPErsistencia = getHelper().darDaoPersistencia();
		}
		catch (SQLException e) 
		{
			
		}
		return daoPErsistencia;
	}
	
	
	//////////////////////////////////////////////////////////////////
	//Metodo para manejo de las imagenes dentro del dispositivo
	//////////////////////////////////////////////////////////////////
	
	/**
	 * Metodo que descarga una imagen de una url y la guarda en el dispostivo
	 * @param bitmap
	 * @param nombre
	 */
	public void descargarImagen(String dirUrl, String nombre)
	{
		URL url;
		Bitmap bitmap = null;
		try 
		{
			url = new URL(dirUrl);

			//Seccion de descarga de la imagen
			HttpURLConnection connection= (HttpURLConnection) url.openConnection();
			connection.setDoInput(true);
			connection.connect();
			InputStream is = connection.getInputStream();
			bitmap=BitmapFactory.decodeStream(is);


			//Seccion de almacenamiento de la imagen
			ByteArrayOutputStream bytes = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
			FileOutputStream fos = openFileOutput(nombre, Context.MODE_WORLD_WRITEABLE);
			fos.write(bytes.toByteArray());
			fos.close();
		} 
		catch (MalformedURLException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		catch (IOException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * Metodo utilizado para eliminar una imagen. Este se usa para los updates y los deletes
	 * @param nombre
	 */
	public void eliminarImagen(String nombre)
	{
		this.deleteFile(nombre);
	}
	
	
	//////////////////////////////////////////////////////////////////
	//Metodo para gpasar a otras actividades
	//////////////////////////////////////////////////////////////////
	
	/**
	 * Metodo para pasar a la actividad familia.
	 */
	public void pasarAFamily()
	{
		Intent intent = new Intent(this, com.mini.familia.Familia1.class);
		startActivity(intent);
	}
	
	
	//////////////////////////////////////////////////////////////////
	//Metodos de la clase activity
	//////////////////////////////////////////////////////////////////
	
	
	/**
	 * Metodo que retorna el contexto de esta actividad
	 * @return
	 */
	public Context darContexto()
	{
		return this;
	}


}